#include<iostream>
#include<string>
#include<unistd.h>
#include<pthread.h>
#include<ctime>

#define NUM 10

using namespace std;

enum
{
    OK=0,
    ERROR
};

class ThreadData
{
public:
    ThreadData(const string& name,int id,time_t createTime,int top)
    :_name(name)
    ,_id(id)
    ,_createTime((uint64_t)createTime)
    ,_status(OK)
    ,_top(top)
    ,_result(0)
    {}
    ~ThreadData()
    {}
public:
    //输入的
    string _name;//线程名
    int _id;//线程id
    uint64_t _createTime;//线程创建时间

    //返回的
    int _status;//线程状态
    int _top;//求和至哪个整数
    int _result;//返回求和结果
};
void *thread_run(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);

    for(int i = 1; i <= td->_top; i++)
    {
        td->_result += i;
    }
    cout << td->_name << " cal done!" << endl;
    return td;
    
    // while (true)
    // {
    //     cout << "thread is running, name " << td->_name << " create time: " << td->_createTime << " index: " << td->_id << endl;
    //     // // exit(10); // 进程退出，不是线程退出，只要有任何一个线程调用exit，整个进程(所有线程)全部退出！
    //     // sleep(4);
        
    //     // break;
    // }
    // delete td;

    // pthread_exit((void*)2);   // void *ret = (void*)1;
    // return nullptr;
}
int main()
{

    //1.创建线程
    pthread_t tids[NUM];

    for(int i=0;i<NUM;i++)
    {
        char tname[64];
        //1.1将字符串格式化进tname
        snprintf(tname,64,"thread-%d",i+1);
        //1.2创建类对象：线程名，线程id，线程创建的时间戳，top表示求和到哪个整数
        ThreadData* td = new ThreadData(tname,i+1,time(nullptr),100+5*i);

        //1.3
        //thread：获取创建成功的线程ID，该参数是一个输出型参数。
        //创建线程的属性，传入NULL表示使用默认属性
        //线程启动后要执行的函数,这里用的是thread_run函数
        //传给线程例程的参数,我们自定义了一个求和整数的类对象
        pthread_create(tids+i,nullptr,thread_run,td);//创建线程，td是thread_run函数的参数,
        //同时td也是我们自己创建的类对象
        sleep(1);
    }

    //2.等待线程
    void *ret = nullptr;
    for(int i=0;i<NUM;i++)
    {
        //int pthread_join(pthread_t thread, void **retval);,注意是void**类型的
        //被等待线程的id，获取线程退出码
        int n = pthread_join(tids[i],&ret);

        if(n!=0)
        {
            cerr << "pthread_join error" << endl;
        }
        //获取线程退出码，将ret强制转换成ThreadData*
        ThreadData* td = static_cast<ThreadData*>(ret);

        if(td->_status == OK)
        {
            cout << td->_name << " 计算的结果是: " << td->_result << " (它要计算的是[1, " << td->_top << "])" <<endl;
        }
        delete td;
    }
    cout << "all thread quit..." << endl;
    return 0;
}
